package com.xm.myapplication.View;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.animation.LinearInterpolator;

import com.xm.myapplication.R;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;

/**
 * loading
 */

public class LoadingImageView extends AppCompatImageView {
    public static final int DEFAULT_SHADOW_COLOR = 0x60000000;
    public static final int DEFAULT_BGCOLOR_COLOR = 0xff424242;
    private boolean mIsLoading = false;
    private boolean mIsOval;//是否需要加载圆形
    private float mRoundedCorner;//圆角大小
    private Bitmap mBitmapLoad;
    private Bitmap mBitmapBg;
    private int mDegree = 0;
    private ValueAnimator mValueAnimator;
    private Matrix mMatrix;

    public LoadingImageView(Context context) {
        super(context);
        init();
    }

    public LoadingImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LoadingImageView);
        if (ta != null) {
            mIsOval = ta.getBoolean(R.styleable.LoadingImageView_is_oval, false);
            mRoundedCorner = ta.getDimensionPixelOffset(R.styleable.LoadingImageView_rounded_corner, -1);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mIsLoading) {
            canvas.drawBitmap(getBitmapBg(), 0, 0, null);
            mMatrix.setRotate(mDegree, (float) mBitmapLoad.getWidth() / 2, (float) mBitmapLoad.getHeight() / 2);
            mMatrix.postTranslate(getWidth() / 2 - mBitmapLoad.getWidth() / 2, getHeight() / 2 - mBitmapLoad.getHeight() / 2);
            canvas.drawBitmap(mBitmapLoad, mMatrix, null);
        }
    }

    private void init() {
        mMatrix = new Matrix();
        mBitmapLoad = BitmapFactory.decodeResource(getResources(), R.mipmap.loading);
    }

    private Bitmap getBitmapBg() {
        if (mBitmapBg == null) {
            mBitmapBg = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            Canvas tempCanvas = new Canvas(mBitmapBg);
            tempCanvas.drawColor(DEFAULT_SHADOW_COLOR);
        }
        if (mIsOval) {
            return getOvalBitmap(mBitmapBg);
        }
        if (mRoundedCorner > 0) {
            return getRoundedCornerBitmap(mBitmapBg, mRoundedCorner);
        }
        return mBitmapBg;
    }

    private Bitmap getOvalBitmap(Bitmap bitmap) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(DEFAULT_BGCOLOR_COLOR);
        canvas.drawOval(rectF, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    private Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(DEFAULT_BGCOLOR_COLOR);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    private void startAnim() {
        if (mValueAnimator == null) {
            mValueAnimator = ValueAnimator.ofInt(0, 360);
            mValueAnimator.setDuration(2000);
            mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
            mValueAnimator.setInterpolator(new LinearInterpolator());
            mValueAnimator.addUpdateListener(animation -> {
                mDegree = (int) animation.getAnimatedValue();
                invalidate();
            });
            mValueAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationCancel(Animator animation) {
                    super.onAnimationCancel(animation);
                    invalidate();
                }
            });
        }
        if (!mValueAnimator.isRunning()) {
            mValueAnimator.start();
        }
    }

    private void stopAnim() {
        if (mValueAnimator != null && mValueAnimator.isRunning()) {
            mValueAnimator.cancel();
        }
    }

    public void setLoadingStatus(boolean isLoading) {
        this.mIsLoading = isLoading;
        if (mIsLoading) {
            startAnim();
        } else {
            stopAnim();
        }
    }

    public boolean isLoading() {
        return mIsLoading;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.i("destroy", "destroy");
        if (mBitmapBg != null) {
            mBitmapBg.recycle();
        }
        if (mBitmapLoad != null) {
            mBitmapLoad.recycle();
        }
    }
}
